import Service from './Service';
import UrlMgr from './UrlMgr';

class HttpHandler {
    private _successHandle: Function | null;
    private _failHandle: Function | null;
    private _requestType: string | null;
    private _requestData: any | null;
    private _retry: boolean;

    constructor(successHandle: Function, failHandle: Function, requestType: string) {
        this._successHandle = null;
        this._failHandle = null;
        this._requestType = null;
        this._requestData = null;
        this._retry = false;

        this.setHandler(successHandle, failHandle, requestType);
    }

    public setHandler(successHandle: Function, failHandle: Function, requestType: string): HttpHandler {
        this.setRequest(requestType);
        this._successHandle = successHandle;
        this._failHandle = failHandle;
        return this;
    }

    public setRequest(requestType: string): HttpHandler {
        this._requestType = requestType;
        this._requestData = null;
        this._retry = UrlMgr.getInstance().needEnqueue(this._requestType);
        return this;
    }

    public setRequestData(requestData: any = null): HttpHandler {
        this._requestData = requestData;
        return this;
    }

    public setRetry(retry: boolean): HttpHandler {
        this._retry = retry;
        return this;
    }

    public success(data: any): boolean {
        if (this._successHandle) {
            this._successHandle(data);
        }
        this.recover();
        return false;
    }

    public fail(error: any): boolean {
        if (this._failHandle) {
            this._failHandle(error);
        }
        if (this._retry) {
            return true;
        }
        this.recover();
        return false;
    }

    public needRetry(): boolean {
        return this._retry;
    }

    public enterQueue(): boolean {
        return UrlMgr.getInstance().needEnqueue(this._requestType);
    }

    public getRequestType(): string | null {
        return this._requestType;
    }

    public getRequestData(): any | null {
        return this._requestData;
    }

    public clear(): HttpHandler {
        this._requestType = null;
        this._requestData = null;
        if (this._successHandle) {
            this._successHandle = null;
        }
        if (this._failHandle) {
            this._failHandle = null;
        }
        return this;
    }

    public recover(): void {
        HttpHandler.pool.push(this.clear());
    }

    public handleRequest(): void {
        Service.request(this);
    }

    private static pool: HttpHandler[] = [];

    public static create(successHandle: Function, failHandle: Function, requestType: string): HttpHandler {
        if (HttpHandler.pool.length) {
            const handler = HttpHandler.pool.pop();
            return handler ? handler.setHandler(successHandle, failHandle, requestType) : new HttpHandler(successHandle, failHandle, requestType);
        } else {
            return new HttpHandler(successHandle, failHandle, requestType);
        }
    }
}

export default HttpHandler;